﻿namespace BattleShip
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    public class PlaySpace
    {
        private int countOfDestroyedShip = 10;
        private int[,] matrix;
        private int[] arrayWithShipsPoints;
        public List<List<string>> allShips;
        public Render rend;
        public Player player;

        public PlaySpace(Player player)
        {
            matrix = new int[10, 10];
            rend = new Render(player);
            this.player = player;
        }

        public int CountOfDestroyedShip
        {
            get { return this.countOfDestroyedShip; }
        }

        public void FillPlaySpace(List<List<string>> coordinates)
        {
            allShips = coordinates;
            arrayWithShipsPoints = new int[coordinates.Count() + 1];
            for (int i = 0; i < coordinates.Count; i++)
            {
                arrayWithShipsPoints[i + 1] = coordinates[i].Count();
                foreach (var item in coordinates[i])
                {
                    var currentSpot = item.Split();
                    int x = int.Parse(currentSpot[0]);
                    int y = int.Parse(currentSpot[1]);
                    matrix[x, y] = i + 1;
                }
            }
            if (this.player == Player.Human)
            {
                for (int i = 0; i < 10; i++)
                {
                    for (int k = 0; k < 10; k++)
                    {
                        if (matrix[i, k] != 0)
                        {
                            rend.Draw(i, k, 'X', ConsoleColor.DarkYellow);
                        }
                    }
                }
            }
        }

        public Dictionary<string, StatmentOfPositionInMatrix> ReturnStat(string coordinates)
        {
            Dictionary<string, StatmentOfPositionInMatrix> hittedPosition = new Dictionary<string, StatmentOfPositionInMatrix>();
            int x = int.Parse(coordinates[0].ToString());
            int y = int.Parse(coordinates[2].ToString());

            if (matrix[x, y] != 0)
            {
                if (arrayWithShipsPoints[matrix[x, y]] > 1)
                {
                    arrayWithShipsPoints[matrix[x, y]]--;
                    matrix[x, y] = 0;
                    rend.Draw(x, y, 'O', ConsoleColor.Red);
                    hittedPosition.Add(coordinates, StatmentOfPositionInMatrix.Hitted);
                    return hittedPosition;
                }
                else if (arrayWithShipsPoints[matrix[x, y]] == 1)
                {
                    countOfDestroyedShip--;
                    matrix[x, y] = 0;
                    rend.Draw(x, y, 'X', ConsoleColor.Red);
                    int shipIndex = FoundTheShip(x, y);
                    foreach (var coordinate in allShips[shipIndex])
                    {
                        hittedPosition.Add(coordinate, StatmentOfPositionInMatrix.Destroyed);
                    }

                    DrawWhenIsDestroyed(shipIndex);
                    return hittedPosition;
                }

                throw new ArgumentException("Problem with calculating values!");
            }
            else
            {
                rend.Draw(x, y, 'o', ConsoleColor.Blue);
                hittedPosition.Add(coordinates, StatmentOfPositionInMatrix.Empty);
                return hittedPosition;
            }
        }

        private bool GotShipOnPosition(int x, int y)
        {
            if (matrix[x, y] != 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private int FoundTheShip(int x, int y)
        {
            for (int i = 0; i < allShips.Count; i++)
            {
                foreach (var item in allShips[i])
                {
                    var currentSpot = item.Split();
                    int tempX = int.Parse(currentSpot[0]);
                    int tempY = int.Parse(currentSpot[1]);
                    if (x == tempX && y == tempY)
                    {
                        return i;
                    }
                }
            }

            throw new ArgumentException("Invalid Method WORK!!!");
        }

        private void DrawWhenIsDestroyed(int shipIndex)
        {
            HashSet<string> coordinateForChange = new HashSet<string>();
            foreach (var coordinate in allShips[shipIndex])
            {
                string[] coordinatesArr = coordinate.Split(' ');
                int xCoordinate = int.Parse(coordinatesArr[0]);
                int yCoordinate = int.Parse(coordinatesArr[1]);

                // UpLeft -1, -1
                if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate - 1, yCoordinate - 1))
                {
                    string strCoordinate = (xCoordinate - 1).ToString() + " " + (yCoordinate - 1).ToString();
                    if (!coordinateForChange.Contains(strCoordinate))
                    {
                        coordinateForChange.Add(strCoordinate);
                        rend.Draw(xCoordinate - 1, yCoordinate - 1, 'o', ConsoleColor.Cyan);
                    }
                }

                // UpMid -1, 0
                if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate - 1, yCoordinate))
                {
                    string strCoordinate = (xCoordinate - 1).ToString() + " " + yCoordinate.ToString();
                    if (!coordinateForChange.Contains(strCoordinate))
                    {
                        coordinateForChange.Add(strCoordinate);
                        rend.Draw(xCoordinate - 1, yCoordinate, 'o', ConsoleColor.Cyan);
                    }
                }

                // UpRight -1, +1
                if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate - 1, yCoordinate + 1))
                {
                    string strCoordinate = (xCoordinate - 1).ToString() + " " + (yCoordinate + 1).ToString();
                    if (!coordinateForChange.Contains(strCoordinate))
                    {
                        coordinateForChange.Add(strCoordinate);
                        rend.Draw(xCoordinate - 1, yCoordinate + 1, 'o', ConsoleColor.Cyan);
                    }
                }

                // MidLeft 0, -1
                if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate, yCoordinate - 1))
                {
                    string strCoordinate = xCoordinate.ToString() + " " + (yCoordinate - 1).ToString();
                    if (!coordinateForChange.Contains(strCoordinate))
                    {
                        coordinateForChange.Add(strCoordinate);
                        rend.Draw(xCoordinate, yCoordinate - 1, 'o', ConsoleColor.Cyan);
                    }
                }

                // MidRight 0, +1
                if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate, yCoordinate + 1))
                {
                    string strCoordinate = xCoordinate.ToString() + " " + (yCoordinate + 1).ToString();
                    if (!coordinateForChange.Contains(strCoordinate))
                    {
                        coordinateForChange.Add(strCoordinate);
                        rend.Draw(xCoordinate, yCoordinate + 1, 'o', ConsoleColor.Cyan);
                    }
                }

                // DownLeft +1 , -1
                if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate + 1, yCoordinate - 1))
                {
                    string strCoordinate = (xCoordinate + 1).ToString() + " " + (yCoordinate - 1).ToString();
                    if (!coordinateForChange.Contains(strCoordinate))
                    {
                        coordinateForChange.Add(strCoordinate);
                        rend.Draw(xCoordinate + 1, yCoordinate - 1, 'o', ConsoleColor.Cyan);
                    }
                }

                // DownMid +1, 0
                if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate + 1, yCoordinate))
                {
                    string strCoordinate = (xCoordinate + 1).ToString() + " " + yCoordinate.ToString();
                    if (!coordinateForChange.Contains(strCoordinate))
                    {
                        coordinateForChange.Add(strCoordinate);
                        rend.Draw(xCoordinate + 1, yCoordinate, 'o', ConsoleColor.Cyan);
                    }
                }

                // DownRight +1, +1
                if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate + 1, yCoordinate + 1))
                {
                    string strCoordinate = (xCoordinate + 1).ToString() + " " + (yCoordinate + 1).ToString();
                    if (!coordinateForChange.Contains(strCoordinate))
                    {
                        coordinateForChange.Add(strCoordinate);
                        rend.Draw(xCoordinate + 1, yCoordinate + 1, 'o', ConsoleColor.Cyan);
                    }
                }
            }

            foreach (var coordinate in allShips[shipIndex])
            {
                string[] coordinatesArr = coordinate.Split(' ');
                int xCoordinate = int.Parse(coordinatesArr[0]);
                int yCoordinate = int.Parse(coordinatesArr[1]);
                rend.Draw(xCoordinate, yCoordinate, 'X', ConsoleColor.Red);
            }
        }
    }
}